/**
 * Created by jiachenpan on 16/11/18.
 */

export function parseTime(time, cFormat) {
  if (typeof time === 'undefined' || time === null) {
    return '--'
  }
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (('' + time).length === 10) time = parseInt(time) * 1000
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

export function formatTime(time, option) {
  time = +time * 1000
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) { // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分'
  }
}

/*
* 参数说明：
* number：要格式化的数字
* decimals：保留几位小数
* dec_point：小数点符号
* thousands_sep：千分位符号
*/
export function numberFormat(number, decimals = 2, dec_point = '.', thousands_sep = ' ') {
  number = (number + '').replace(/[^0-9+-Ee.]/g, '')
  const n = !isFinite(+number) ? 0 : +number
  const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
  const sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep
  const dec = (typeof dec_point === 'undefined') ? '.' : dec_point
  let s = ''
  const toFixedFix = function(n, prec) {
    var k = Math.pow(10, prec)
    return '' + Math.ceil(n * k) / k
  }

  s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
  var re = /(-?\d+)(\d{3})/
  while (re.test(s[0])) {
    s[0] = s[0].replace(re, '$1' + sep + '$2')
  }

  if ((s[1] || '').length < prec) {
    s[1] = s[1] || ''
    s[1] += new Array(prec - s[1].length + 1).join('0')
  }
  return s.join(dec)
}

/**
 * JavaScript对象的深浅复制
 * @param {*} obj
 */
export function deepCopy(obj) {
  let newObj = obj.constructor === Array ? [] : {}
  newObj.constructor = obj.constructor

  if (typeof obj !== 'object') {
    return
  } else if (window.JSON) {
    //若需要考虑特殊的数据类型，如正则，函数等，需把这个else if去掉即可
    newObj = JSON.parse(JSON.stringify(obj))
  } else {
    for (var prop in obj) {
      if (obj[prop].constructor === RegExp || obj[prop].constructor === Date) {
        newObj[prop] = obj[prop]
      } else if (typeof obj[prop] === 'object') {
        //递归
        newObj[prop] = deepCopy(obj[prop])
      } else {
        newObj[prop] = obj[prop]
      }
    }
  }
  return newObj
}

/**
 * 去抖动
 * @param {*} func 回调函数
 * @param {*} wait 等待毫秒
 * @param {*} immediate 是否立即执行
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function(...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

//去左右空格;
export function trim(s) {
  return s.replace(/(^\s*)|(\s*$)/g, '')
}

// 深copy对象
export function CopyJson(json) {
  //同型元素
  var ptList = []
  //找出各类元素(元素，路径，寻找历史)
  var allPath = []
  function _getAllKeyType(Obj, Key, Path, LogList) {
    //添加寻找历史
    if (!Key) Key = '$'
    if (!Path) Path = '$'
    if (!LogList) LogList = []
    LogList.push({ Key: Key, Obj: Obj, Path: Path })
    for (var key in Obj) {
      var keyPath = Path + '.' + key
      //判断是否包含key
      if (!Obj.hasOwnProperty(key)) continue
      if (typeof Obj[key] === 'object' && Obj[key] != null) {
        //判断是否是
        var FindParentObj = LogList.find(p => Object.is(p.Obj, Obj[key]))
        //如果是添加并跳出
        if (FindParentObj != null) {
          ptList.push({ Path: keyPath, Parent: FindParentObj.Path, Key: key, ParentKey: FindParentObj.Key })
          continue
        }
        allPath.push(keyPath)
        _getAllKeyType(Obj[key], key, keyPath, LogList)
      }
    }
  }
  _getAllKeyType(json)
  //寻找同级元素
  function _copyjson(p, cc, Jpath) {
    if (!Jpath) {
      Jpath = '$'
    }
    const c = cc || {}
    for (var i in p) {
      if (!p.hasOwnProperty(i)) {
        continue
      }
      if (typeof p[i] === 'object') {
        var kypath = Jpath + '.' + i
        if (ptList.find(q => q.Path === kypath) != null) continue
        switch ((Object.prototype.toString.call(p[i])).toLowerCase().split(' ')[1].replace(']', '')) {
          case 'array':
            c[i] = []
            break
          case 'object':
            c[i] = {}
            break
          case 'null':
            c[i] = null
            break
          default: break
        }
        //不是同型元素
        _copyjson(p[i], c[i], kypath)
      } else {
        c[i] = p[i]
      }
    }
    return c
  }
  var newcpyjson = _copyjson(json)
  function _jsonpath(obj, findpath) {
    findpath.split('.').forEach(p => {
      if (typeof (obj) !== 'undefined' && p !== '$' && obj != null) {
        obj = obj[p]
      }
    })
    return obj
  }
  while (ptList.length > 0) {
    var p = ptList.shift()
    if (p.Parent !== '$' && allPath.find(fq => fq === p.Parent) == null) {
      ptList.push(p)
    } else {
      var ptObj = _jsonpath(newcpyjson, p.Parent)
      // console.log(JSON.stringify(p))
      // console.log(ptObj)
      var _pathlist = p.Path.split('.')
      _pathlist.pop()
      var sonObj = _jsonpath(newcpyjson, _pathlist.join('.'))
      sonObj[p.Key] = ptObj
      allPath.push(p.Path)
    }
  }
  return newcpyjson
}
